package service

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"sync"

	"github.com/uber-go/zap"
)

/* 定时加载所有的应用，写入最新版本号*/

var releaseVer map[string]string
var configVer map[string]string

var lock = sync.RWMutex{}

func ScanApps() {
	for {
		// ts := time.Now()

		releaseVer = make(map[string]string)
		configVer = make(map[string]string)

		// 获取所有APP目录名
		filepath.Walk("./resources", func(path string, f os.FileInfo, err error) error {
			n := strings.Count(path, "/")

			if f.IsDir() && n == 1 && f.Name() != "resources" {

				// 找到应用目录下的version.new
				// 获取到version文件名

				v, err := getVersion(path + "/releases/version.new")
				if err != nil {
					Logger.Warn("read version.new error", zap.String("app", f.Name()), zap.Error(err))
					return err
				}

				lock.Lock()
				releaseVer[f.Name()] = string(v)
				lock.Unlock()

				// 获取configs
				pc := path + "/configs"
				pe, _ := PathExists(pc)
				if pe {
					// 判断一下底下是否存在groups
					p := pc + "/version.new"
					v, _ := getVersion(p)
					if v != "" {
						lock.Lock()
						configVer[f.Name()] = string(v)
						lock.Unlock()
					} else {
						// 遍历groups，获取config version
						filepath.Walk(pc, func(path string, f1 os.FileInfo, err error) error {
							if f1.IsDir() {
								p := pc + "/" + f1.Name() + "/version.new"
								v, _ := getVersion(p)
								if v != "" {
									lock.Lock()
									configVer[f.Name()+"/"+f1.Name()] = string(v)
									lock.Unlock()
								}
							}
							return nil
						})
					}
				}
			}

			return nil
		})

		time.Sleep(Conf.Server.AppsReadInterval)
	}
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func getVersion(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()

	v, err := ioutil.ReadAll(f)
	if err != nil {
		return "", err
	}

	return string(v), nil
}
